#include <QDebug>
#include <QTimer>
#include <QByteArray>
#include "csingleapplication.h"

CSingleApplication::CSingleApplication(int argc, char *argv[], const QString &key)
    :QCoreApplication(argc, argv)
{
    sharedMemory.setKey(key);

    if (sharedMemory.attach())
    {
        _isRunning = true;
    }
    else
    {
        _isRunning = false;

        // default value to note that no message is available.
        QByteArray byteArray("0");

        /* create shared memory */
        if (!sharedMemory.create(5000))
        {
            qDebug("Unable to create single instance.");
            return;
        }

        /* copy message to shared memory */
        sharedMemory.lock();
        char *to = (char*)sharedMemory.data();
        const char *from = byteArray.data();
        memcpy(to, from, qMin(sharedMemory.size(), byteArray.size()));
        sharedMemory.unlock();

        /* start checking for messages from other instances. */
        QTimer *timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()), this, SLOT(checkForMessage()));
        timer->start(500);      // call "checkForMessage()" every 500ms
    }
}

void CSingleApplication::checkForMessage()
{
    sharedMemory.lock();
    QByteArray byteArray = QByteArray((char*)sharedMemory.constData(), sharedMemory.size());
    sharedMemory.unlock();

    // there is no message
    if (byteArray.left(1) == "0")
        return;

    /* read message  */
    byteArray.remove(0, 1);
    QString message = QString::fromUtf8(byteArray.constData());
    if (!message.isNull() && !message.isEmpty())
    {
        // remove message from shared memory.
        byteArray = "0";
        sharedMemory.lock();
        char *to = (char*)sharedMemory.data();
        const char *from = byteArray.data();
        memcpy(to, from, qMin(sharedMemory.size(), byteArray.size()));
        sharedMemory.unlock();

        emit messageAvailable(message);
    }
}

bool CSingleApplication::isRunning()
{
    return _isRunning;
}

bool CSingleApplication::sendMessage(const QString &message)
{
    if (!_isRunning)
        return false;

    /* transform string message to raw data */
    QByteArray byteArray("1");
    byteArray.append(message.toUtf8());
    byteArray.append('\0');

    /* write message into shared memory */
    sharedMemory.lock();
    char *to = (char*)sharedMemory.data();
    const char *from = byteArray.data();
    memcpy(to, from, qMin(sharedMemory.size(), byteArray.size()));
    sharedMemory.unlock();

    return true;
}

CSingleApplication::~CSingleApplication()
{
    if (sharedMemory.isAttached())
    {
        sharedMemory.detach();
    }
}
